package com.wolfcode.appointment.service.impl;

import java.math.BigDecimal;
import java.util.HashSet;
import java.util.List;

import com.wolfcode.appointment.domain.BusStatement;
import com.wolfcode.appointment.domain.vo.BusStatementAndStatementItemVo;
import com.wolfcode.appointment.domain.vo.BusStatementWithItemVo;
import com.wolfcode.appointment.enums.BusStatementEnum;
import com.wolfcode.appointment.mapper.BusStatementMapper;
import com.wolfcode.appointment.service.IBusStatementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.wolfcode.appointment.mapper.BusStatementItemMapper;
import com.wolfcode.appointment.domain.BusStatementItem;
import com.wolfcode.appointment.service.IBusStatementItemService;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;


/**
 * 结算单明细Service业务层处理
 *
 * @author wolfcode
 * @date 2022-11-25
 */
@Service
public class BusStatementItemServiceImpl implements IBusStatementItemService {
    @Autowired
    private BusStatementItemMapper busStatementItemMapper;
    @Autowired
    private IBusStatementService busStatementService;
    @Autowired
    private BusStatementMapper busStatementMapper;

    /**
     * 查询结算单明细
     *
     * @param id 结算单明细主键
     * @return 结算单明细
     */
    @Override
    public BusStatementItem selectBusStatementItemById(Long id) {
        return busStatementItemMapper.selectBusStatementItemById(id);
    }

    /**
     * 查询结算单明细列表
     *
     * @param busStatementItem 结算单明细
     * @return 结算单明细
     */
    @Override
    public List<BusStatementItem> selectBusStatementItemList(BusStatementItem busStatementItem) {
        return busStatementItemMapper.selectBusStatementItemList(busStatementItem);
    }

    /**
     * 新增结算单明细
     *
     * @param busStatementItem 结算单明细
     * @return 结果
     */
    @Override
    public int insertBusStatementItem(BusStatementItem busStatementItem) {
        return busStatementItemMapper.insertBusStatementItem(busStatementItem);
    }

    /**
     * 修改结算单明细
     *
     * @param busStatementItem 结算单明细
     * @return 结果
     */
    @Override
    public int updateBusStatementItem(BusStatementItem busStatementItem) {
        return busStatementItemMapper.updateBusStatementItem(busStatementItem);
    }

    /**
     * 批量删除结算单明细
     *
     * @param ids 需要删除的结算单明细主键
     * @return 结果
     */
    @Override
    public int deleteBusStatementItemByIds(Long[] ids) {
        return busStatementItemMapper.deleteBusStatementItemByIds(ids);
    }

    /**
     * 删除结算单明细信息
     *
     * @param id 结算单明细主键
     * @return 结果
     */
    @Override
    public int deleteBusStatementItemById(Long id) {
        return busStatementItemMapper.deleteBusStatementItemById(id);
    }

    /**
     * 保存结算单明细
     *
     * @param busStatementAndStatementItemVo
     * @return
     */
    @Override
    public void save(BusStatementAndStatementItemVo busStatementAndStatementItemVo) {
        // 1. 关卡(数据合法性)
        Assert.notNull(busStatementAndStatementItemVo, "非法参数");
        // 校验集合是否为空
        List<BusStatementItem> busStatementItems = busStatementAndStatementItemVo.getBusStatementItems();
        Assert.notEmpty(busStatementItems, "结算单明细表不能为空");
        // 结算单明细表不能存在空元素
        Assert.noNullElements(busStatementItems, "结算单明细表存在空明细");
        BusStatementWithItemVo busStatementWithItemVo = busStatementAndStatementItemVo.getBusStatementWithItemVo();
        Assert.notNull(busStatementWithItemVo, "结算单不能为空");

        // 2关卡  （保存一张结算单，对应多个明细）
        boolean pass = checkUniqueStatement(busStatementItems);
        Assert.state(pass, "只能保存一张结算单");
        // 3关卡 （状态校验） 已支付不用保存，消费中才可以保存
        Long statementId = busStatementItems.get(0).getStatementId();
        // 数据库结算单查询，需要结算单id
        BusStatement busStatement = busStatementService.selectBusStatementById(statementId);
        Assert.state(busStatement.getStatus() == BusStatementEnum.CONSUMING.ordinal()
                , "消费中才可以保存");
        // 4落库
        // 新增结算单明细 | 更新结算单明细
        // statementId存在明细，我先删除
        List<BusStatementItem> statementItems = busStatementItemMapper
                .selectBusStatementItemByStatementId(statementId);
        if (!CollectionUtils.isEmpty(statementItems)) {
            busStatementItemMapper.deleteBusStatementItemByStatementId(statementId);
        }
        BigDecimal totalAmount = new BigDecimal(0);
        long totalQuantity = 0;
        for (BusStatementItem busStatementItem : busStatementItems) {
            busStatementItemMapper.insertBusStatementItem(busStatementItem);
            // 总的价格
            totalAmount = totalAmount.add(busStatementItem.getItemPrice().multiply(new BigDecimal(busStatementItem.getItemQuantity() + "")));
            // 计算服务总数量
            totalQuantity += busStatementItem.getItemQuantity();

        }
        // 计算出来之后TotalAmount,才去判断
        // 校验总消费不能小于优惠价格
        Assert.state(totalAmount
                        .compareTo(busStatementWithItemVo.getDiscountAmount()) > 0,
                "优惠价格不能大于总价格");
        // 更新结算单
        BusStatement updateStatement = new BusStatement();
        updateStatement.setId(statementId);
        // 总消费
        updateStatement.setTotalAmount(totalAmount);
        // 折扣价
        updateStatement.setDiscountAmount(busStatementWithItemVo.getDiscountAmount());
        // 总服务项数量
        updateStatement.setTotalQuantity(new BigDecimal(totalQuantity));
        busStatementMapper.updateBusStatement(updateStatement);
    }

    /**
     * 校验结算单明细数据的唯一性
     *
     * @param busStatementItems
     * @return
     */
    private boolean checkUniqueStatement(List<BusStatementItem> busStatementItems) {
        HashSet<Object> set = new HashSet<>();
        for (BusStatementItem busStatementItem : busStatementItems) {
            // 结算单id
            set.add(busStatementItem.getStatementId());
        }
        return set.size() == 1;
    }
}
